﻿using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.IO.Ports;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using Ymodem;



namespace yomdem_test
{
    public partial class Form1 : Form
    {
        //String szBinPath = "";
        public Form1()
        {
            InitializeComponent();
            this.AutoScaleMode = AutoScaleMode.Dpi;
            CheckForIllegalCrossThreadCalls = false;
            //初始化调用
            EnumComportfromReg(comboBox1);
            serialPort1.Encoding = Encoding.UTF8;
            //comboBox1.SelectedIndex = 0;
            //cmb_baud.SelectedIndex = 1;
        }
        Thread thread;
        private delegate void FlushClient(); //代理
        int packetNumber = 0;
        string path;

        int fsLen;
        private void EnumComportfromReg(ToolStripComboBox Combobox)
        {

            Combobox.Items.Clear();
            string[] ArryPort = SerialPort.GetPortNames();
            for (int i = 0; i < ArryPort.Length; i++)
            {
                Combobox.Items.Add(ArryPort[i]);
            }
            if (ArryPort.Length > 0)
            {
                comboBox1.SelectedIndex = 0;
                cmb_baud.SelectedIndex = 5;
                comboBox4.SelectedIndex = 5;
                Parity_combox.SelectedIndex = 0;
            }
        }

        /*
         * Upload file via Ymodem protocol to the device
         * ret: is the transfer succeeded? true is if yes
         */

        private void ThreadFunction()
        {
            if (this.txb_section.InvokeRequired)//等待异步
            {
                FlushClient fc = new FlushClient(ThreadFunction);
                this.Invoke(fc); //通过代理调用刷新方法
            }
            else
            {
                this.txb_section.Text = packetNumber.ToString();
                pgb_download.Value = (int)(((float)packetNumber / (float)fsLen) * 100) % 100;
            }
        }
        public void converthextobin(string szHexPath)
        {
            {
                Int32 i = 0;
                Int32 j = 0;
                Int32 maxAddr = 0;        //HEX文件的最大地址
                Int32 segAddr = 0;        //段地址
                Int32 first = 0;
                Int32 row = 0;
                Int32 sum = 0;
                try
                {
                    String szLine = "";
                    String szHex = "";
                    if (szHexPath == "")
                    {
                        MessageBox.Show("请选择需要转换的目标文件!         ", "错误");
                        return;
                    }

                    StreamReader HexReader = new StreamReader(szHexPath);

                    //先找出HEX文件的最大地址
                    while (true)
                    {
                        szLine = HexReader.ReadLine(); //读取一行数据
                        i++;
                        if (szLine == null) //读完所有行
                        {
                            break;
                        }
                        if (szLine.Substring(0, 1) == ":") //判断第1字符是否是:
                        {

                            if (szLine.Substring(1, 8) == "00000001")//数据结束
                            {
                                break;
                            }
                            if (szLine.Substring(7, 2) == "04")
                            {
                                segAddr = Int32.Parse(szLine.Substring(9, 4), NumberStyles.HexNumber);      //800
                                segAddr *= 16;
                            }
                            else if (szLine.Substring(7, 2) == "00")
                            {
                                int len_row = szLine.Length;
                                Int32 tmpAddr = Int32.Parse(szLine.Substring(3, 4), NumberStyles.HexNumber);
                                tmpAddr += UInt16.Parse(szLine.Substring(1, 2), NumberStyles.HexNumber);
                                tmpAddr += segAddr;
                                row++;
                                sum = row * 16;
                                //  if (len_row < 42)
                                //  sum -= Int32.Parse(szLine.Substring(1, 2), NumberStyles.HexNumber);

                                if (tmpAddr > maxAddr)
                                    maxAddr = tmpAddr;
                            }

                        }
                        else
                        {
                            MessageBox.Show("错误:不是标准的hex文件!");
                            return;
                        }

                    }

                    //新建一个二进制文件,填充为0XFF
                    byte[] szBin = new byte[sum];

                    //MessageBox.Show("size" + szBin.Length);
                    ////for (i = 0; i < maxAddr; i++)
                    ////    szBin[i] = 0XFF;
                    ////返回文件开头
                    HexReader.BaseStream.Seek(0, SeekOrigin.Begin);
                    HexReader.DiscardBufferedData();//不加这句不能正确返回开头 
                    segAddr = 0;

                    //根据hex文件地址,填充bin文件
                    while (true)
                    {

                        szLine = HexReader.ReadLine(); //读取一行数据

                        if (szLine == null) //读完所有行
                        {
                            break;
                        }
                        if (szLine.Substring(0, 1) == ":") //判断第1字符是否是:
                        {

                            if (szLine.Substring(1, 8) == "00000001")//数据结束
                            {
                                break;
                            }

                            if (szLine.Substring(7, 2) == "04")
                            {
                                segAddr = Int32.Parse(szLine.Substring(9, 4), NumberStyles.HexNumber);
                                segAddr *= 16;
                            }
                            if (szLine.Substring(7, 2) == "00")
                            {
                                int tmpAddr = Int32.Parse(szLine.Substring(3, 4), NumberStyles.HexNumber);
                                int num = Int16.Parse(szLine.Substring(1, 2), NumberStyles.HexNumber);
                                // MessageBox.Show("size" + num);
                                tmpAddr += segAddr;
                                j = 0;
                                for (i = 0; i < num; i++)
                                {
                                    szBin[first++] = (byte)Int16.Parse(szLine.Substring(j + 9, 2), NumberStyles.HexNumber);
                                    j += 2;
                                }

                            }
                        }

                    }

                    HexReader.Close(); //关闭目标文件


                    //  if (path == "")
                    {
                        path = Path.ChangeExtension(szHexPath, "bin");
                        //tbBinPath.Text = szBinPath;
                    }
                    FileStream fs = new FileStream(path, FileMode.Create);

                    //将byte数组写入文件中
                    fs.Write(szBin, 0, szBin.Length);
                    //所有流类型都要关闭流，否则会出现内存泄露问题                
                    fsLen = (int)fs.Length / 1000;                    //计算总段长
                    txb_totalsection.Text = fsLen.ToString();
                    fs.Close();

                    string tmp = "文件转换完成! 文件大小: ";
                    tmp += sum.ToString();
                    tmp += "字节";


                    // FileStream fBin = new FileStream(path, FileMode.Create); //创建文件BIN文件
                    // BinaryWriter BinWrite = new BinaryWriter(fBin); //二进制方式打开文件
                    // BinWrite.Write(szBin, 0, maxAddr); //写入数据
                    // BinWrite.Flush();//释放缓存
                    // BinWrite.Close();//关闭文件
                    // //string tmp = "文件转换完成! 文件大小: ";
                    //// tmp += maxAddr.ToString();
                    //// tmp += "字节";
                    richTextBox1.AppendText(tmp);
                    //MessageBox.Show(tmp, "提示");
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }

            }

        }
        public bool YmodemUploadFile()
        {
            /* control signals */
            const byte STX = 2;  // Start of TeXt 
            const byte EOT = 4;  // End Of Transmission
            const byte ACK = 6;  // Positive ACknowledgement
            const byte C = 67;   // capital letter C
            /* sizes */
            const int dataSize = 1024;
            const int crcSize = 2;
            /* THE PACKET: 1029 bytes */
            /* header: 3 bytes */
            // STX        
            int invertedPacketNumber = 255;
            /* data: 1024 bytes */
            byte[] data = new byte[dataSize];
            /* footer: 2 bytes */
            byte[] CRC = new byte[crcSize];
            /* get the file */
            FileStream fileStream;
            try
            {
                fileStream = new FileStream(@path, FileMode.Open, FileAccess.Read);                 //读取bin文件的path 
            }
            catch (System.Exception ex)
            {
                richTextBox1.AppendText("错误：文件打开失败\r\n");
                btn_download.Enabled = true;
                return false;
            }

            DateTime dt = DateTime.Now;
            byte[] ack;
            ack = new byte[] { 0x31 };
            try
            {
                serialPort1.Write(ack, 0, 1);
            }
            catch
            {
                MessageBox.Show("Exception");
                btn_download.Enabled = true;
            }
            Thread.Sleep(300);
            try
            {
                /* send the initial packet with filename and filesize */
                /*  if (serialPort1.ReadByte() != C)
                  {
                      Console.WriteLine("Can't begin the transfer.");
                      return false;
                  }*/

                sendYmodemInitialPacket(STX, packetNumber, invertedPacketNumber, data, dataSize, path, fileStream, CRC, crcSize);

                if (serialPort1.ReadByte() != ACK)
                {
                    MessageBox.Show("Can't send the initial packet.");
                    restart();
                    return false;
                }
                Thread.Sleep(300);
                if (serialPort1.ReadByte() != C)
                    return false;

                /* send packets with a cycle until we send the last byte */
                int fileReadCount;
                do
                {
                    /* if this is the last packet fill the remaining bytes with 0 */

                    fileReadCount = fileStream.Read(data, 0, dataSize);

                    if (fileReadCount == 0) break;
                    if (fileReadCount != dataSize)
                        for (int i = fileReadCount; i < dataSize; i++)
                            data[i] = 0;
                    /* calculate packetNumber */
                    packetNumber++;
                    if (packetNumber > 255)
                        packetNumber -= 256;
                    ThreadFunction();
                    //Console.WriteLine(packetNumber);

                    /* calculate invertedPacketNumber */
                    invertedPacketNumber = 255 - packetNumber;

                    /* calculate CRC */
                    Crc16Ccitt crc16Ccitt = new Crc16Ccitt(InitialCrcValue.Zeros);
                    CRC = crc16Ccitt.ComputeChecksumBytes(data);

                    /* send the packet */
                    sendYmodemPacket(STX, packetNumber, invertedPacketNumber, data, dataSize, CRC, crcSize);

                    /* wait for ACK */
                    if (serialPort1.ReadByte() != ACK)
                    {
                        // Console.WriteLine("Couldn't send a packet.");
                        return false;
                    }
                } while (dataSize == fileReadCount);

                /* send EOT (tell the downloader we are finished) */
                serialPort1.Write(new byte[] { EOT }, 0, 1);
                /* send closing packet */
                packetNumber = 0;
                invertedPacketNumber = 255;
                data = new byte[dataSize];
                CRC = new byte[crcSize];
                sendYmodemClosingPacket(STX, packetNumber, invertedPacketNumber, data, dataSize, CRC, crcSize);
                /* get ACK (downloader acknowledge the EOT) */
                if (serialPort1.ReadByte() != ACK)
                {
                    //Console.WriteLine("Can't complete the transfer.");
                    return false;
                }
            }
            catch (TimeoutException)
            {
                btn_download.Enabled = true;
                throw new Exception("Eductor does not answering");
            }
            finally
            {
                fileStream.Close();
            }
            btn_download.Enabled = true;
            TimeSpan span = DateTime.Now - dt;
            btn_download.Invoke
           (
               //委托，托管无参数的任何方法
               new MethodInvoker
               (
                   delegate
                   {
                       btn_download.Text = "烧录完成";
                   }
               )
            );


            File.Delete(path);
            pgb_download.Value = 100;
            Thread.Sleep(1000);
            this.richTextBox1.SelectionFont = new Font(richTextBox1.Font.Name, 14);
            richTextBox1.AppendText("User Time:" + span.ToString() + "\r\n");
            this.richTextBox1.SelectionFont = new Font(richTextBox1.Font.Name, 14);
            richTextBox1.AppendText("Programming Successful\r\n");
            // this.richTextBox1.SelectionFont = new Font(richTextBox1.Font.Name, 9);
            btn_download.Text = "开始烧录";
            pgb_download.Value = 0;
            // btn_download.Text = "k";
            return true;
        }

        private void sendYmodemInitialPacket(byte STX, int packetNumber, int invertedPacketNumber, byte[] data, int dataSize, string path, FileStream fileStream, byte[] CRC, int crcSize)
        {
            string fileName = System.IO.Path.GetFileName(path);
            string fileSize = fileStream.Length.ToString();

            /* add filename to data */
            int i;
            for (i = 0; i < fileName.Length && (fileName.ToCharArray()[i] != 0); i++)
            {
                data[i] = (byte)fileName.ToCharArray()[i];
            }
            data[i] = 0;

            /* add filesize to data */
            int j;
            for (j = 0; j < fileSize.Length && (fileSize.ToCharArray()[j] != 0); j++)
            {
                data[(i + 1) + j] = (byte)fileSize.ToCharArray()[j];
            }
            data[(i + 1) + j] = 0;

            /* fill the remaining data bytes with 0 */
            for (int k = ((i + 1) + j) + 1; k < dataSize; k++)
            {
                data[k] = 0;
            }

            /* calculate CRC */
            Crc16Ccitt crc16Ccitt = new Crc16Ccitt(InitialCrcValue.Zeros);
            CRC = crc16Ccitt.ComputeChecksumBytes(data);

            /* send the packet */
            sendYmodemPacket(STX, packetNumber, invertedPacketNumber, data, dataSize, CRC, crcSize);
        }

        private void sendYmodemClosingPacket(byte STX, int packetNumber, int invertedPacketNumber, byte[] data, int dataSize, byte[] CRC, int crcSize)
        {
            /* calculate CRC */
            Crc16Ccitt crc16Ccitt = new Crc16Ccitt(InitialCrcValue.Zeros);
            CRC = crc16Ccitt.ComputeChecksumBytes(data);

            /* send the packet */
            sendYmodemPacket(STX, packetNumber, invertedPacketNumber, data, dataSize, CRC, crcSize);
        }

        private void sendYmodemPacket(byte STX, int packetNumber, int invertedPacketNumber, byte[] data, int dataSize, byte[] CRC, int crcSize)
        {
            serialPort1.Write(new byte[] { STX }, 0, 1);
            serialPort1.Write(new byte[] { (byte)packetNumber }, 0, 1);
            serialPort1.Write(new byte[] { (byte)invertedPacketNumber }, 0, 1);
            serialPort1.Write(data, 0, dataSize);
            serialPort1.Write(CRC, 0, crcSize);
        }

        private void btn_select_hex_Click(object sender, EventArgs e)
        {
            openFileDialog1.ShowDialog();
            btn_download.Enabled = true;
        }

        private void hexfileloadthread()
        {
            YmodemUploadFile();
        }
        private void openFileDialog1_FileOk(object sender, CancelEventArgs e)
        {
            path = openFileDialog1.FileName;
            richTextBox1.AppendText("文件：" + path + "\r\n");
            string strpath = System.IO.Path.GetExtension(path);
            if (strpath == ".hex")
            {
                converthextobin(path);

            }
            else
            {
                FileStream fileStream = new FileStream(@path, FileMode.Open, FileAccess.Read);
                fsLen = (int)fileStream.Length / 1000;                    //计算总段长
                txb_totalsection.Text = fsLen.ToString();
            }

        }

        private void btn_port_Click(object sender, EventArgs e)
        {
            if (serialPort1.IsOpen)
            {
                try
                {
                    serialPort1.Close();
                    uart_lable.Text = "未连接";
                    btn_port.Text = "启动串口";
                    comboBox1.Enabled = true;
                    cmb_baud.Enabled = true;
                    Parity_combox.Enabled = true;
                    toolStripButton1.Enabled = true;

                }
                catch (Exception ex)
                {
                    if (tabControl1.SelectedIndex == 0)
                    {
                        richTextBox1.AppendText("错误：串口异常\r\n");
                    }
                    else
                    {
                        richTextBox2.AppendText("错误：串口异常\r\n");
                    }

                    return;
                }

            }
            else
            {

                int baud = int.Parse(cmb_baud.Text);
                serialPort1.PortName = comboBox1.Text;
                serialPort1.BaudRate = baud;
                serialPort1.Parity = getSerialParity();// Parity.None;

                try
                {
                    serialPort1.Open();
                    ThreadTest tt = new ThreadTest(serialPort1, (richTextBox3), tabControl1,radioButton1);//创建线程测试类，这个类是一个普通类
                    thread = new Thread(new ThreadStart(tt.ActionMethod));
                    thread.Start();//启动线程
                    uart_lable.Text = "已连接";
                    btn_port.Text = "关闭串口";
                    comboBox1.Enabled = false;
                    cmb_baud.Enabled = false;
                    toolStripButton1.Enabled = false;
                    Parity_combox.Enabled = false;
                }
                catch (Exception ex)
                {
                    if (tabControl1.SelectedIndex == 0)
                    {
                        richTextBox1.AppendText("错误：串口异常\r\n");
                    }
                    else
                    {
                        richTextBox2.AppendText("错误：串口异常\r\n");
                    }
                    uart_lable.Text = "未连接";
                    btn_port.Text = "启动串口";
                    comboBox1.Enabled = true;
                    cmb_baud.Enabled = true;
                    toolStripButton1.Enabled = true;
                    return;
                }

            }
        }

        private Parity getSerialParity()
        {
            if (Parity_combox.Equals("Even"))
            {
                return Parity.Even;
            }else if (Parity_combox.Equals("None"))
            {
                return Parity.None;
            }
            else if (Parity_combox.Equals("Odd"))
            {
                return Parity.Odd;
            }
            else if (Parity_combox.Equals("Mark"))
            {
                return Parity.Mark;
            }
            else if (Parity_combox.Equals("Space"))
            {
                return Parity.Space;
            }
            return Parity.None;
        }

        int GetIndexof(byte [] bytes,int index,int size ,byte bb)
        {
            for (int i = index; i < size; i++)
            {
                if (bytes[i] == bb)
                    return i;
            }
            return -1;
        }
        [DllImport("msvcrt.dll", CallingConvention = CallingConvention.Cdecl)]
        static extern int memcmp(byte[] b1, byte[] b2, long count);

        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
      
            // serialPort1.ReadExisting(); 
            if (tabControl1.SelectedIndex == 0)
            {
                string str = serialPort1.ReadExisting();
                richTextBox1.AppendText(str);
                if (str.Contains("#######"))
                {
                    try
                    {
                        timer1.Stop();
                        toolStripLabel1.Text = "未连接";

                        richTextBox1.AppendText("监听成功，进入BootLoader\r\n");

                    }
                    catch (System.Exception ex)
                    {

                    }
                }
            }
            else if (tabControl1.SelectedIndex == 1)
            {
                string str = serialPort1.ReadExisting();
                richTextBox2.AppendText(str);
            }
            else
            {
                
            } 
        }

        private void btn_download_Click(object sender, EventArgs e)
        {
            if (!serialPort1.IsOpen)
            {
                richTextBox1.AppendText("错误：检查串口是否打开\r\n");
                return;
            }

            Thread th = new Thread(hexfileloadthread);
            th.Start();
            btn_download.Enabled = false;
            btn_download.Text = "正在烧录";
            this.txb_section.Text = "0";
        }

        private void 联系我ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            About ab_dialog = new About();
            ab_dialog.ShowDialog();
        }

        private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            System.Environment.Exit(0);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            SendStr("1");
        }

        private void button2_Click(object sender, EventArgs e)
        {
            SendStr("2");
        }

        private void button6_Click(object sender, EventArgs e)
        {

            SendStr("AT+UPDATE\r\n");
        }

        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {
            richTextBox1.SelectionStart = richTextBox1.Text.Length; //Set the current caret position at the end
            richTextBox1.ScrollToCaret(); //Now scroll it automatically
        }

        private void button7_Click(object sender, EventArgs e)
        {
            richTextBox1.Clear();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private void 帮助ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                if (tabControl1.SelectedIndex == 0)
                {
                    richTextBox1.Text = "";
                    this.richTextBox1.SelectionFont = new Font(richTextBox1.Font.Name, 12);
                    richTextBox1.AppendText(
    @"帮助文档：
    1、该软件可以用来烧录任何支持Ymodem协议的芯片固件，支持bin文件和hex文件。
    2、节点在进入boot模式下，直接点击开始烧录，即可开始烧录固件。
    3、工具条里面可以选择串口号，和波特率，其他参数全部使用缺省参数。
    4、控制面板区域按钮功能：
        打开文件：打开要烧录的.hex或者.bin文件。
        进入启动：通过串口发送'AT+UPDATE\r\n'指令。
        清空：清空消息面板。
        复位：通过串口发送'AT+RESET'指令。
        重置：通过串口发送'AT+FACRESET'指令。
    5、自定义功能区域按钮功能：
        进入更新：通过串口发送'1'指令。
        运行APP：通过串口发送'2'指令。
        取消更新：通过串口发送'a'指令。
        验证秘钥：通过串口发送'12341234'指令。
    6、固件更新区域介绍：
	    开始烧录：单击该按钮，可以开始烧录固件。
	    烧录段号：正在烧录的固件段号。
	    总段长：固件的总长度。
    7、开始烧录之后等待进度条走完即可烧录完成，消息面板会显示烧录成功的消息。
");
                }
                else if (tabControl1.SelectedIndex == 1)
                {
                    richTextBox2.Text = "";
                    this.richTextBox2.SelectionFont = new Font(richTextBox2.Font.Name, 12);
                    richTextBox2.AppendText(
    @"帮助文档：
    1、该软件可以用来更新lora L78S节点的deveui,appeui,appkey,chmask,需要节点代码支持。
    2、工具条里面可以选择串口号，和波特率，其他参数全部使用缺省参数。
    3、自定义按钮留作备用，暂时没有使用。
    4、控制面板区域，清空消息按钮可以去清除消息面板的消息。
    5、参数配置区域：
        按照 APPEUI DEVEUI APPKEY（excel表格内容复制一行直接粘贴即可）的顺序粘贴节点ID到参数配置的文本框内，粘贴前请清除文本框中的内容（双击可以清除），数据之间有空格，回车，换行，制表符可忽略，软件会自动清除不可见字符，如果需要粘贴ID到代码中，点击上面的图片可自动生成C格式数组
    6、终端控制区域按钮：
        复位：通过串口发送'AT+RESET\r\n'指令。
        保存：通过串口发送'AT+SAVE\r\n'指令。
        UART模式：通过串口发送'AT+MODE=UART\r\n'指令。
        重置：通过串口发送'AT+FACRESET\r\n'指令。
");
                }
                else
                {
                    richTextBox3.Text = "";
                    this.richTextBox3.SelectionFont = new Font(richTextBox2.Font.Name, 12);
                    richTextBox3.AppendText(
    @"帮助文档：
    1、该页面用作亿连内部协议实现。
    2、工具条里面可以选择串口号，和波特率，其他参数全部使用缺省参数，如果需要设置请提需求。
    3、自定义按钮留作备用，暂时没有使用。
    4、控制面板区域，清空消息按钮可以去清除消息面板的消息。
    5、参数配置区域：
        按照 APPEUI DEVEUI APPKEY（excel表格内容复制一行直接粘贴即可）的顺序粘贴节点ID到参数配置的文本框内，粘贴前请清除文本框中的内容（双击可以清除），数据之间有空格，回车，换行，制表符可忽略，软件会自动清除不可见字符，如果需要粘贴ID到代码中，点击上面的图片可自动生成C格式数组
    6、终端控制区域：
        生产模式：可根据按钮左侧波特率自动组合亿连内部协议的数据帧，发送至串口，同时按照该波特率修改串口参数，并且会将左侧单选框设置为生产模式，显示hex字符，开始解析串口数据帧。
        lora参数写入：通过识别左侧“参数配置区域”内容，进行deveui，appeui，appkey的数据帧打包，同时发送到串口。
        lora参数读取：会发送亿连内部规约中读取全部lora参数的数据帧，同时在接受线程里面会解析接受到的数据帧。
        单选框：单选框选中生产模式的时候串口会解析当前接受到的数据帧，选中调试模式的时候，串口不会解析数据，只会以ascii的方式将数据打印在文本框里面。
");
                }

                //string helpfile = "Ymodem+AT帮助文档.chm";
                // MessageBox.Show(Resource1.ResourceManager.GetObject("Ymodem + AT帮助文档").ToString());
                //Help.ShowHelp(this, helpfile);
                //Help.ShowHelpIndex(this, helpfile);
                //Form2 f = new Form2();
                //f.Show();
            }
            catch (System.Exception ex)
            {
                //MessageBox.Show("没有帮助文档");
            }

        }

        private void pgb_download_Click(object sender, EventArgs e)
        {

        }
        private void SendStr(string str)
        {
            try
            {
                serialPort1.Write(str);
                if (!str.Equals(""))
                {
                    if (tabControl1.SelectedIndex == 0)
                    {
                        richTextBox1.AppendText("Tx:" + str + "\r\n");
                    }
                    else
                    {
                        richTextBox2.AppendText("Tx:" + str + "\r\n");
                    }
                }
            }
            catch (Exception e)
            {
                if (tabControl1.SelectedIndex == 0)
                {
                    richTextBox1.AppendText("错误：检查串口是否打开\r\n");
                }
                else
                {
                    richTextBox2.AppendText("错误：检查串口是否打开\r\n");
                }
                // MessageBox.Show("串口异常");
            }
        }
        public static string ToHexString(byte[] bytes) // 0xae00cf => "AE00CF "

        {
            string hexString = string.Empty;

            if (bytes != null)

            {

                StringBuilder strB = new StringBuilder();

                for (int i = 0; i < bytes.Length; i++)

                {

                    strB.Append(bytes[i].ToString("X2"));

                }

                hexString = strB.ToString();

            }
            return hexString;

        }
        private void SendBytes(Byte[] bytes,int length)
        {
            try
            {
                serialPort1.Write(bytes, 0, length);
               // serialPort1.Write(str);
                if (length > 0)
                {

                    richTextBox3.AppendText("Tx:[" + ToHexString(bytes) + "]\r\n");

                }
            }
            catch (Exception e)
            {
                if (tabControl1.SelectedIndex == 0)
                {
                    richTextBox1.AppendText("错误：检查串口是否打开\r\n");
                }
                else
                {
                    richTextBox2.AppendText("错误：检查串口是否打开\r\n");
                }
                // MessageBox.Show("串口异常");
            }
        }

        private void button27_Click(object sender, EventArgs e)
        {
            richTextBox2.Clear();
        }

        private void button24_Click(object sender, EventArgs e)
        {
            if (checkBox1.Checked)
            {
                SendStr(textBox10.Text + "\r\n");
            }
            else
            {
                SendStr(textBox10.Text);
            }
            //SendStr(textBox10.Text+"\r\n");
        }

        private void button9_Click(object sender, EventArgs e)
        {

            string pristr = manytx_1.Text;
            pristr = Regex.Replace(pristr, "\t", "");
            pristr = Regex.Replace(pristr, "\r", "");
            pristr = Regex.Replace(pristr, "\n", "");
            pristr = Regex.Replace(pristr, " ", "");
            manytx_1.Text = pristr;
            try
            {
                string deveui = "AT+DEVEUI=" + pristr.Substring(16, 16) + "\r\n";
                SendStr(deveui);
                //textBox2.Text = deveui;
                //serialPort1.Write(deveui);
            }
            catch (System.Exception ex)
            {
                MessageBox.Show("检查输入数据,或串口是否打开");
            }
            //SendStr("AT+DEVEUI="+manytx_1.Text+"\r\n");

        }

        private void button13_Click(object sender, EventArgs e)
        {

            try
            {
                string appeui = "AT+APPEUI=" + manytx_1.Text.Substring(0, 16) + "\r\n";
                SendStr(appeui);
            }
            catch (System.Exception ex)
            {
                MessageBox.Show("检查输入数据,或串口是否打开");
            }
        }

        private void button15_Click(object sender, EventArgs e)
        {
            try
            {
                string appkey = "AT+APPKEY=" + manytx_1.Text.Substring(32, 32) + "\r\n";
                SendStr(appkey);
            }
            catch (System.Exception ex)
            {
                MessageBox.Show("检查输入数据,或串口是否打开");
            }

        }

        private void button17_Click(object sender, EventArgs e)
        {
            SendStr("AT+CHMASK=" + comboBox2.Text.Substring(0, 29) + "\r\n");

        }
        private void button10_Click(object sender, EventArgs e)
        {
            if (checkBox2.Checked == true)
            {
                SendStr(textBox1.Text + "\r\n");
            }
            else
            {
                SendStr(textBox1.Text);
            }


        }

        private void button14_Click(object sender, EventArgs e)
        {
            SendStr("AT+RESET=LW502\r\n");
        }

        private void button16_Click(object sender, EventArgs e)
        {
            SendStr("AT+SAVE=LW502\r\n");
        }

        private void richTextBox2_TextChanged(object sender, EventArgs e)
        {
            richTextBox2.SelectionStart = richTextBox2.Text.Length; //Set the current caret position at the end
            richTextBox2.ScrollToCaret(); //Now scroll it automatically
        }

        private void button19_Click(object sender, EventArgs e)
        {
            SendStr("AT+FACTRST=LW502\r\n");
        }

        private void button20_Click(object sender, EventArgs e)
        {
            SendStr("AT+MODE=UART\r\n");
        }

        private void button5_Click(object sender, EventArgs e)
        {
            SendStr("AT+RESET=LW502\r\n");
        }

        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            EnumComportfromReg(comboBox1);
            comboBox1.SelectedIndex = 0;
            cmb_baud.SelectedIndex = 5;
        }

        private void toolStripButton2_Click(object sender, EventArgs e)
        {
            restart();
        }
        private void restart()
        {
            Application.ExitThread();
            Application.Exit();
            Application.Restart();
            System.Diagnostics.Process.GetCurrentProcess().Kill();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            SendStr("a");
        }

        private void button4_Click(object sender, EventArgs e)
        {
            SendStr("12341234");
        }

        private void pictureBox1_Click(object sender, EventArgs e)
        {
            try
            {
                string datapacket = manytx_1.Text;

                datapacket = Regex.Replace(datapacket, "\t", "");
                datapacket = Regex.Replace(datapacket, "\r", "");
                datapacket = Regex.Replace(datapacket, "\n", "");
                datapacket = Regex.Replace(datapacket, " ", "");
                byte[] array = HexStringToByteArray(datapacket);
                for (int i = 0; i < array.Length; i++)
                {
                    if (i == 0)
                    {
                        richTextBox2.AppendText("static uint8_t AppEui[] = {");
                    }
                    if (i == 8)
                    {
                        richTextBox2.AppendText("\r\nstatic uint8_t DevEui[] = {");
                    }
                    if (i == 16)
                    {
                        richTextBox2.AppendText("\r\nstatic uint8_t AppKey[] = {");
                    }
                    if ((i == 7) || (i == 15) || (i == 31))
                    {
                        if (array[i] < 0x0f)
                        {
                            richTextBox2.AppendText("0x0" + Convert.ToString(array[i], 16) + "};");
                        }
                        else
                        {
                            richTextBox2.AppendText("0x" + Convert.ToString(array[i], 16) + "};");
                        }
                    }
                    else
                    {
                        if (array[i] < 0x0f)
                        {
                            richTextBox2.AppendText("0x0" + Convert.ToString(array[i], 16) + ",");
                        }
                        else
                        {
                            richTextBox2.AppendText("0x" + Convert.ToString(array[i], 16) + ",");
                        }
                    }
                }
            }
            catch (System.Exception ex)
            {
                richTextBox2.AppendText("请不要乱点哦！！！\r\n");
            }

        }
        public static byte[] HexStringToByteArray(string s)
        {
            s = s.Replace(" ", "");
            byte[] buffer = new byte[s.Length / 2];
            for (int i = 0; i < s.Length; i += 2)
                buffer[i / 2] = (byte)Convert.ToByte(s.Substring(i, 2), 16);
            return buffer;
        }

        private void pictureBox2_Click(object sender, EventArgs e)
        {
            richTextBox1.AppendText("不要到处乱点哦！！！\r\n");
        }

        private void manytx_1_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            manytx_1.Text = "";
        }

        private void richTextBox1_MouseDoubleClick(object sender, MouseEventArgs e)
        {



        }

        private void button8_Click(object sender, EventArgs e)
        {

        }

        private void toolStripButton2_Click_1(object sender, EventArgs e)
        {
            try
            {

                if (toolStripLabel1.Text.Equals("正在监听"))//
                {
                    toolStripLabel1.Text = "未监听";
                    timer1.Stop();
                }
                else
                {
                    serialPort1.Write("+");
                    timer1.Start();
                    toolStripLabel1.Text = "正在监听";
                    richTextBox1.AppendText("正在监听\r\n");
                }
               
            }
            catch (Exception )
            {
                if (tabControl1.SelectedIndex == 0)
                {
                    richTextBox1.AppendText("错误：检查串口是否打开\r\n");
                }
                else
                {
                    richTextBox2.AppendText("错误：检查串口是否打开\r\n");
                }
            }


        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            try
            {

                serialPort1.Write("+");
            }
            catch (Exception)
            {
                timer1.Stop();
                if (tabControl1.SelectedIndex == 0)
                {
                    richTextBox1.AppendText("错误：检查串口是否打开\r\n");
                }
                else
                {
                    richTextBox2.AppendText("错误：检查串口是否打开\r\n");
                }
            }
        }

        private void button30_Click(object sender, EventArgs e)
        {
            byte[] product = { 0xF0, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xF0, 0x05, 0x01, 0x01, 0x37, 0xF1 };
            if(comboBox4.Text == "2400")
            {
                product[12] = 0x01;
            }
            else if (comboBox4.Text == "9600")
            {
                product[12] = 0x00;
            }
            else if (comboBox4.Text == "600")
            {
                product[12] = 0x02;
            }
            else if (comboBox4.Text == "1200")
            {
                product[12] = 0x03;
            }
            else if (comboBox4.Text == "4800")
            {
                product[12] = 0x04;
            }
            else if (comboBox4.Text == "19200")
            {
                product[12] = 0x05;
            }
            else
            {
                product[12] = 0x01;
            }
            product[13] = 0;
            for (int i = 0;i<13;i++)
            {
                product[13] += product[i];
            }
            SendBytes(product, 15);
            serialPort1.BaudRate = int.Parse(comboBox4.Text);
            cmb_baud.Text = comboBox4.Text;
            radioButton1.Checked = true;

        }

        public static byte[] HexStringToBytes(string hexStr)
        {
            if (string.IsNullOrEmpty(hexStr))
            {
                return (new byte[0]);
            }
            if (hexStr.StartsWith("0x"))
            {
                hexStr = hexStr.Remove(0, 2);
            }
            var count = hexStr.Length; if (count % 2 == 1)
            {
                throw new ArgumentException("Invalid length of bytes:" + count);
            }
            var byteCount = count / 2; var result = new byte[byteCount]; for (int ii = 0; ii < byteCount; ++ii)
            {
                var tempBytes = Byte.Parse(hexStr.Substring(2 * ii, 2), System.Globalization.NumberStyles.HexNumber); result[ii] = tempBytes;
            }
            return (result);
        }




        private void button29_Click(object sender, EventArgs e)
        {
            byte[] bytes = { 0xF0, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xF0, 0x06, 0x28, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x99, 0x99, 0x9A, 0x9B, 0x00, 0x00, 0x00, 0x00, 0x02, 0xC4, 0xCD, 0x82, 0x2F, 0x3B, 0x8B, 0x60, 0x7D, 0x03, 0xCB, 0x8A, 0x06, 0x56, 0x2E, 0x28, 0x0D, 0xBB, 0x78, 0x2D, 0xD5, 0x3B, 0xB7, 0xE8, 0x51, 0x47, 0x6E, 0xF1 } ;
            string pristr = textBox2.Text;
            pristr = Regex.Replace(pristr, "\t", "");
            pristr = Regex.Replace(pristr, "\r", "");
            pristr = Regex.Replace(pristr, "\n", "");
            pristr = Regex.Replace(pristr, " ", "");
            textBox2.Text = pristr;
            try
            {
                byte [] deveui = HexStringToBytes(pristr.Substring(16, 16));
                byte [] appeui = HexStringToBytes(pristr.Substring(0, 16));
                byte [] appkey = HexStringToBytes(pristr.Substring(32, 32));
                richTextBox3.AppendText("==================================================\r\n");
                richTextBox3.AppendText("deveui:"+ToHexString(deveui) + "\r\n");
                richTextBox3.AppendText("appeui:"+ToHexString(appeui) + "\r\n");
                richTextBox3.AppendText("appkey:"+ToHexString(appkey) + "\r\n");
                richTextBox3.AppendText("==================================================\r\n");
                appeui.CopyTo(bytes, 18);
                deveui.CopyTo(bytes, 27);
                appkey.CopyTo(bytes, 36);
                bytes[52] = 0;
                for(int i = 0;i <52;i++)
                {
                    bytes[52] += bytes[i];
                }
                SendBytes(bytes, 54);
            }
            catch (System.Exception ex)
            {
                MessageBox.Show("检查输入数据,或串口是否打开");
            }
        }

        private void button33_Click(object sender, EventArgs e)
        {

        }

        private void button25_Click(object sender, EventArgs e)
        {
            byte[] product = { 0xF0, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xF0, 0x03, 0x08, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01, 0x02, 0x03, 0x44, 0xF1 };
            SendBytes(product, product.Length);
        }

        private void button35_Click(object sender, EventArgs e)
        {
            richTextBox3.Text = "";
        }

        private void textBox2_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            textBox2.Text = "";
        }

        private void button43_Click(object sender, EventArgs e)
        {
            SendStr(textBox3.Text);
        }

        private void richTextBox3_TextChanged(object sender, EventArgs e)
        {
            richTextBox3.SelectionStart = richTextBox2.Text.Length; //Set the current caret position at the end
            richTextBox3.ScrollToCaret(); //Now scroll it automatically
        }

        private void radioButton1_CheckedChanged(object sender, EventArgs e)
        {

        }

        private void textBox2_TextChanged(object sender, EventArgs e)
        {

        }
    }

    public class ThreadTest
    {
        public SerialPort Pss;//串口
        public RichTextBox Pt;//文本区
        public TabControl Ptab;
        public RadioButton Prad;

        public static string ToHexString(byte[] bytes) // 0xae00cf => "AE00CF "
        {
            string hexString = string.Empty;
            if (bytes != null)
            {
                StringBuilder strB = new StringBuilder();
                for (int i = 0; i < bytes.Length; i++)
                {
                    strB.Append(bytes[i].ToString("X2"));
                }
                hexString = strB.ToString();
            }
            return hexString;
        }
        public ThreadTest(SerialPort ss, RichTextBox t, TabControl tab,RadioButton rad)//,Button bu)
        {
            Pss = ss;//串口
            Pt = t;//文本区
            Ptab = tab;//选线卡
            Prad = rad;

        }
        public void ActionMethod()
        {
            byte[] byte1 = new byte[1];
            byte[] byte2 = new byte[255];
            byte[] byte3 = { 0xf0, 0xaa, 0xaa };
            //  Console.Write("进入线程");
            try
            {
                while (Pss.IsOpen)//如果串口没有关闭则接受数据
                {
                    if (Ptab.SelectedIndex == 2)
                    {
                        if (Prad.Checked == true)
                        {
                            int length = Pss.BytesToRead;
                            if (length > 0)
                            {
                                int index = 0;
                                Thread.Sleep(100);
                                length = Pss.BytesToRead;
                                Pt.AppendText("read " + length + "byte\r\n");
                                if (length > 100)
                                {
                                    for (int i = 0; i < length; i++)
                                    {
                                        byte1[0] = (byte)Pss.ReadByte();
                                        // richTextBox3.AppendText(serialPort1.ReadByte() + " ");//Recieve_Data[Recieve_Count++] = this->sPort->ReadByte();
                                        Pt.AppendText(ToHexString(byte1) + " ");
                                    }
                                    Pt.AppendText("\r\n");
                                }
                                else
                                {
                                    for (int i = 0; i < length; i++)
                                    {
                                        byte2[i] = (byte)Pss.ReadByte();
                                    }
                                    for (int i = 0; i < length; i++)
                                    {
                                        if ((byte2[i] == 0xf0) && (byte2[i + 1] == 0xaa) && (byte2[i + 9] == 0xf0))
                                        {
                                            Pt.AppendText("It is a billink frame\r\n");
                                            index = i;
                                            break;
                                        }
                                    }
                                    if (index < length)
                                    {
                                        if (byte2[index + 10] == 0x86)
                                        {
                                            Pt.AppendText("操作成功\r\n");
                                        }
                                        else if (byte2[index + 10] == 0x83)
                                        {
                                            Pt.AppendText("操作成功\r\n");
                                            byte[] deveui = new byte[8];
                                            byte[] appeui = new byte[8];
                                            byte[] appkey = new byte[16];

                                            for (int i = index + 14, j = 0; i < index + 14 + 8; i++, j++)
                                            {
                                                appeui[j] = byte2[i];
                                            }
                                            for (int i = index + 23, j = 0; i < index + 23 + 8; i++, j++)
                                            {
                                                deveui[j] = byte2[i];
                                            }
                                            for (int i = index + 32, j = 0; i < index + 32 + 16; i++, j++)
                                            {
                                                appkey[j] = byte2[i];
                                            }
                                            Pt.AppendText("==================================================\r\n");
                                            Pt.AppendText("deveui:" + ToHexString(deveui) + "\r\n");
                                            Pt.AppendText("appeui:" + ToHexString(appeui) + "\r\n");
                                            Pt.AppendText("appkey:" + ToHexString(appkey) + "\r\n");
                                            Pt.AppendText("==================================================\r\n");
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            string str = Pss.ReadExisting();
                            Pt.AppendText(str);
                        }
                    }
                }
            }
            catch(System.Exception ex)
            {

            }
           
        }
    }

}
